package ru.spb.nicetu.altx.mnemo.extpoint.valuetypes;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.ref.SoftReference;

import org.eclipse.core.resources.IFile;

import ru.spb.nicetu.altx.mnemo.math.managers.ValueTypeClassManager;
import ru.spb.nicetu.altx.mnemo.utils.FileValueSaveLoadUtil;
import ru.spb.nicetu.altx.mnemo.utils.NullValueException;


/**
 * Прокси-ITemplateValueType с отложенной загрузкой реального Значения 
 * из файла.<br>
 * Загруженное реальное Значение хранится как SoftReference, чтобы сборщик 
 * мусора мог его подчищать.
 */
@SuppressWarnings("serial")
public class ProxyValueType extends AProxyValueType {

  //**************************************************************************//
  //                        Enums                                             //
  //**************************************************************************//

  //**************************************************************************//
  //                        Members                                           //
  //**************************************************************************//
  @SuppressWarnings("unchecked")
  private SoftReference<ITemplateValueType> referenceToOriginalValue
    = new SoftReference<ITemplateValueType>(null);
  
  private IFile file;
  //**************************************************************************//
  //                        Constructors                                      //
  //**************************************************************************//
  public ProxyValueType() {
    super();
  }
  
  public ProxyValueType(IFile file) {
    this();
    this.file = file;
  }
  //**************************************************************************//
  //                        Getters                                           //
  //**************************************************************************//

  //**************************************************************************//
  //                        Setters                                           //
  //**************************************************************************//

  //**************************************************************************//
  //                        Publics                                           //
  //**************************************************************************//
  public boolean hasAliveValue() {
    return (this.referenceToOriginalValue.get() != null);
  }

  
  @SuppressWarnings("unchecked")
  @Override
  public ITemplateValueType getOriginalValue() {
    ITemplateValueType originalValue = this.referenceToOriginalValue.get();
    if (originalValue != null) 
      return originalValue;
    
    originalValue = loadOriginalValue();
    this.referenceToOriginalValue = new SoftReference<ITemplateValueType>(originalValue);
    return originalValue;
  }

  @SuppressWarnings("unchecked")
  public ITemplateValueType clone() {
    ProxyValueType clone = null;
    clone = new ProxyValueType(this.file);
    return clone;
  }
  
  //**************************************************************************//
  //                        Abstracts                                         //
  //**************************************************************************//

  //**************************************************************************//
  //                        Protected                                         //
  //**************************************************************************//

  public IFile getFile(){
    return file;
  }
  //**************************************************************************//
  //                        Privates                                          //
  //**************************************************************************//
  @SuppressWarnings("unchecked")
  private ITemplateValueType loadOriginalValue() {
    ITemplateValueType originalValue = null;
    try {
      System.out.println("PRE loadOriginalValue()");
      originalValue = FileValueSaveLoadUtil.LoadRealValue(this.file);
      System.out.println("POST loadOriginalValue()");
    } catch (FileNotFoundException e) {
      e.printStackTrace();
    } catch (IOException e) {
      e.printStackTrace();
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    } catch (NullValueException e) {
    		System.err.println("NullValueException in ProxyValueType.loadOriginalValue()");
    		String valueClassName = e.getMessage();
        try {
          originalValue = (ITemplateValueType) ValueTypeClassManager.getInstance()
              .getValueTypeClass(valueClassName).newInstance();
        } catch (InstantiationException e1) {
          e1.printStackTrace();
        } catch (IllegalAccessException e1) {
          e1.printStackTrace();
        }
//      e.printStackTrace();
    }
    return originalValue;
  }
  //**************************************************************************//
  //                        Public Statics                                    //
  //**************************************************************************//

  //**************************************************************************//
  //                        Private Statics                                   //
  //**************************************************************************//

  //**************************************************************************//
  //                        Internal Classes                                  //
  //**************************************************************************//
}
